package org.example.onlinejudge.service;

import org.example.onlinejudge.model.Permission;
import org.example.onlinejudge.model.Role;
import org.example.onlinejudge.model.User;
import org.example.onlinejudge.repository.PermissionRepository;
import org.example.onlinejudge.repository.RoleRepository;
import org.example.onlinejudge.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

/**
 * 用户服务类
 * 负责处理用户相关的业务逻辑和数据操作
 * 实现逻辑：
 * 1. 提供用户注册功能，支持指定角色（教师/学生）
 * 2. 实现用户信息查询、更新、删除等基本操作
 * 3. 提供用户角色管理功能（添加/移除角色）
 * 4. 实现用户状态管理（启用/禁用）和密码修改功能
 * 5. 使用PasswordEncoder加密用户密码，确保安全性
 * 6. 通过@Transactional注解确保数据操作的事务性
 */
@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private PermissionRepository permissionRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * 检查用户是否存在
     */
    public boolean userExists(String username) {
        return userRepository.existsByUsername(username);
    }

    /**
     * 检查邮箱是否存在
     */
    public boolean emailExists(String email) {
        if (email == null || email.trim().isEmpty()) {
            return false;
        }
        return userRepository.existsByEmail(email);
    }

    /**
     * 创建新用户（注册时使用） - 默认学生角色
     */
    @Transactional
    public User createUser(String username, String password, String email, String nickname) {
        return createUserWithRole(username, password, email, nickname, "2");
    }

    /**
     * 创建新用户并指定角色（注册时使用）
     * @param roleCode 角色代码：1-老师, 2-学生
     */
    @Transactional
    public User createUserWithRole(String username, String password, String email, String nickname, String roleCode) {
        System.out.println("\n====== 开始注册新用户 ======");
        System.out.println("用户名: " + username);
        System.out.println("角色代码: " + roleCode + " (" + (roleCode.equals("1") ? "教师" : "学生") + ")");
        
        // 检查用户名是否已存在
        if (userExists(username)) {
            System.out.println("❌ 注册失败：用户名已存在");
            throw new IllegalArgumentException("用户名已存在");
        }

        // 检查邮箱是否已存在
        if (email != null && !email.trim().isEmpty() && emailExists(email)) {
            System.out.println("❌ 注册失败：邮箱已被使用");
            throw new IllegalArgumentException("邮箱已被使用");
        }

        // 验证角色代码
        if (!roleCode.equals("1") && !roleCode.equals("2")) {
            System.out.println("❌ 注册失败：无效的角色代码");
            throw new IllegalArgumentException("无效的角色代码");
        }

        // 创建用户实体
        User user = new User();
        user.setUsername(username);
        user.setPassword(passwordEncoder.encode(password));
        user.setEmail(email);
        user.setName(nickname != null && !nickname.trim().isEmpty() ? nickname : username);
        user.setEnabled(true);
        
        System.out.println("✓ 用户实体创建完成");

        // 分配指定角色
        Optional<Role> roleOpt = roleRepository.findByRoleCode(roleCode);
        if (roleOpt.isPresent()) {
            Role role = roleOpt.get();
            user.addRole(role);
            System.out.println("✓ 角色分配完成: " + role.getRoleName() + " (ID: " + role.getId() + ")");
            System.out.println("✓ 该角色拥有 " + role.getPermissions().size() + " 个权限");
        } else {
            String roleName = roleCode.equals("1") ? "老师" : "学生";
            System.out.println("❌ 注册失败：角色不存在");
            throw new IllegalStateException("角色（" + roleName + "）不存在，请先初始化角色数据");
        }

        // 保存用户（JPA会自动处理用户-角色关系表）
        System.out.println("💾 正在保存用户到数据库...");
        User savedUser = userRepository.save(user);
        
        System.out.println("✅ 用户保存成功！用户ID: " + savedUser.getId());
        System.out.println("✅ 用户-角色关系已自动插入到 sys_user_role 表");
        System.out.println("✅ 用户已继承角色的所有权限（通过 sys_role_perm 表）");
        System.out.println("====== 注册完成 ======\n");
        
        return savedUser;
    }

    /**
     * 根据用户名查找用户
     */
    public Optional<User> findByUsername(String username) {
        return userRepository.findByUsername(username);
    }

    /**
     * 根据用户名查找用户（包含角色信息）
     */
    public Optional<User> findByUsernameWithRoles(String username) {
        return userRepository.findByUsernameWithRoles(username);
    }

    /**
     * 根据ID查找用户
     */
    public Optional<User> findById(Long id) {
        return userRepository.findById(id);
    }

    /**
     * 获取所有用户
     */
    public List<User> findAllUsers() {
        return userRepository.findAll();
    }

    /**
     * 更新用户信息
     */
    @Transactional
    public User updateUser(User user) {
        return userRepository.save(user);
    }

    /**
     * 删除用户
     */
    @Transactional
    public void deleteUser(Long userId) {
        userRepository.deleteById(userId);
    }

    /**
     * 为用户添加角色
     */
    @Transactional
    public void addRoleToUser(Long userId, Long roleId) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new IllegalArgumentException("用户不存在"));
        Role role = roleRepository.findById(roleId)
                .orElseThrow(() -> new IllegalArgumentException("角色不存在"));
        
        user.addRole(role);
        userRepository.save(user);
    }

    /**
     * 移除用户的角色
     */
    @Transactional
    public void removeRoleFromUser(Long userId, Long roleId) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new IllegalArgumentException("用户不存在"));
        Role role = roleRepository.findById(roleId)
                .orElseThrow(() -> new IllegalArgumentException("角色不存在"));
        
        user.removeRole(role);
        userRepository.save(user);
    }

    /**
     * 启用/禁用用户
     */
    @Transactional
    public void setUserEnabled(Long userId, boolean enabled) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new IllegalArgumentException("用户不存在"));
        user.setEnabled(enabled);
        userRepository.save(user);
    }

    /**
     * 修改密码
     */
    @Transactional
    public void changePassword(Long userId, String newPassword) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new IllegalArgumentException("用户不存在"));
        user.setPassword(passwordEncoder.encode(newPassword));
        userRepository.save(user);
    }

    /**
     * 获取用户总数
     */
    public long getUserCount() {
        return userRepository.count();
    }

    /**
     * 为用户添加直接权限
     */
    @Transactional
    public void addPermissionToUser(Long userId, Long permissionId) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new IllegalArgumentException("用户不存在"));
        Permission permission = permissionRepository.findById(permissionId)
                .orElseThrow(() -> new IllegalArgumentException("权限不存在"));
        
        user.addPermission(permission);
        userRepository.save(user);
    }

    /**
     * 移除用户的直接权限
     */
    @Transactional
    public void removePermissionFromUser(Long userId, Long permissionId) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new IllegalArgumentException("用户不存在"));
        Permission permission = permissionRepository.findById(permissionId)
                .orElseThrow(() -> new IllegalArgumentException("权限不存在"));
        
        user.removePermission(permission);
        userRepository.save(user);
    }

    /**
     * 获取用户的所有权限（包括角色权限和直接权限）
     */
    public Set<Permission> getAllPermissionsForUser(Long userId) {
        User user = userRepository.findByIdWithRoles(userId)
                .orElseThrow(() -> new IllegalArgumentException("用户不存在"));
        
        Set<Permission> allPermissions = new HashSet<>();
        
        // 添加角色权限
        for (Role role : user.getRoles()) {
            allPermissions.addAll(role.getPermissions());
        }
        
        // 添加直接权限
        allPermissions.addAll(user.getPermissions());
        
        return allPermissions;
    }
}



